package com.lu.edu.controller;

import com.alibaba.fastjson.JSON;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.lu.edu.dao.AllDemoDto;
import com.lu.edu.dao.ProcessInstanceDTO;
import com.lu.edu.utils.ConstantValues;
import com.lu.edu.utils.result.CommonResult;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import liquibase.pro.packaged.S;
import org.flowable.engine.RepositoryService;
import org.flowable.engine.RuntimeService;

import org.flowable.engine.TaskService;
import org.flowable.engine.repository.Deployment;
import org.flowable.engine.runtime.ProcessInstance;
import org.flowable.task.api.Task;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;

import javax.validation.constraints.NotBlank;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @Author: 雨同我
 * @Description:
 * @DateTime: 2024/7/10 16:22
 **/
@Api(tags = { "审批流程接口" })
@RequestMapping(value = "/process")
@RestController
public class FlowableController {

    @Autowired
    private RepositoryService repositoryService;
    @Autowired
    private TaskService taskService;
    @Autowired
    private RuntimeService runtimeService;

    @GetMapping("test")
    private CommonResult findUserAgentTask(String user) {
        //1.查找指定用户的一个待办任务
        List<Task> list = taskService.createTaskQuery()
                .taskAssignee(user)
                .list();
        //2.返回待办任务的id
        return CommonResult.success(list.get(0));
    }


    @GetMapping("rollback")
    private CommonResult rollback(String processInstanceId) {
        Task sourceTask = taskService.createTaskQuery()
                .processInstanceId(processInstanceId)
                .active()
                .singleResult();

        return CommonResult.success(200);
    }


    /**
     * @Description: 流程变量，局部和全局
     * runtimeService--> ACT_RU_EXECUTION   id
     * taskService-->  act_ru_task
     *
     * 局部变量
     * runtimeService.setVariableLocal(execution.getId(), "formProp1", "someLocalValue");
     *
     * 全局
     * Map<String, Object> variables = new HashMap<>();
     * variables.put("myVar", "someValue");
     * ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("processKey", variables);
     *
     * 注意点：
     * 指定的id，对应的key，val可以覆盖，和map类似
     *
     * @Author: 雨同我
     * @DateTime: 2024/7/10 16:46
     * @param: null: 
     * @return: 
    */
    @PostMapping("localVar")
    private CommonResult demo(@RequestBody AllDemoDto allDemoDto) {
        System.out.println(JSON.toJSON(allDemoDto));

        Map<String, Object> local = new HashMap<String, Object>(){{
            put("局部",allDemoDto.getLocalValue());
        }};
        taskService.setVariablesLocal(allDemoDto.getTaskId(),local);

        Map<String, Object> all = new HashMap<String, Object>(){{
            put("全局",allDemoDto.getWholeValue());
        }};
        runtimeService.setVariables(allDemoDto.getExecutionId(),all);
        return CommonResult.success(200);
    }




    /**
     * @Description: 部署流程
     * @Author: 雨同我
     * @DateTime: 2024/7/9 10:35
     * @param: null:
     * @return:
     */
    @GetMapping("/deploy")
    public CommonResult deployDef(){
        Deployment deploy = repositoryService.createDeployment()
                .addClasspathResource("processes/request-approval-resource.bpmn.xml")
                .name("测试2")
                .deploy();
        return CommonResult.success(deploy);
    }


    /**
     * @Description: 对于的表
     * SELECT * FROM act_re_procdef WHERE ID_="7847e87d-3c0b-11ef-bbf5-00e0990005cc"
     * @Author: 雨同我
     * @DateTime: 2024/7/9 11:31
     * @param: null:
     * @return:
     */

    @GetMapping("startById")
    public CommonResult startById(String processId ){
        System.out.println("processId"+processId);
        ProcessInstance processInstance = runtimeService.startProcessInstanceById(processId);
        return CommonResult.success(processInstance);
    }

    /**
     * @Description:    测试用例 juniorAdmin=user&requestUser=test&resourceId=aaaaaa&seniorAdmin=admin
     * @Author: 雨同我
     * @DateTime: 2024/7/9 17:44
     * @param: null:
     * @return:
     */
    @PostMapping("/begin")
    @ApiOperation(value = "启动一个审批流程", notes = "根据给定的用户参数来启动一个审批流程")
    public CommonResult startProcessInstance(@RequestBody AllDemoDto allDemoDto) {
        String resourceId=allDemoDto.getDeployResourceId();
        String requestUser=allDemoDto.getDeployRequestUser();
        String juniorAdmin= allDemoDto.getDeployJuniorAdmin();
        String seniorAdmin=allDemoDto.getDeploySeniorAdmin();


        //这里将启动时相关参数附带到流程实例变量中，为后续接口和BPMN查询使用
        Map<String, Object> variables = new HashMap<>();
        variables.put("resourceId", resourceId);// 请求的资源ID
        variables.put("requestUser", requestUser);// 请求发起用户
        variables.put("juniorAdmin", juniorAdmin); // 初级审批用户
        variables.put("seniorAdmin", seniorAdmin); // 高级审批用户
        ProcessInstance instance=runtimeService.startProcessInstanceByKey(ConstantValues.FLOWABLE_PROCESS_BPMN_KEY, variables);

        System.out.println("instance.getId()"+instance.getId());
        Map<String, Object> all = new HashMap<String, Object>(){{
            put("全局","v1");
        }};
        runtimeService.setVariables(instance.getId(),all);


        ProcessInstanceDTO ret=new ProcessInstanceDTO();
        ret.setProcessInstanceId(instance.getProcessInstanceId());
        ret.setProcessDeploymentId(instance.getDeploymentId());

        return CommonResult.success(instance);
    }



    @GetMapping("/complete")
    @ResponseBody
    @ApiOperation(value = "审批指定的任务", notes = "审批指定的任务")
    public CommonResult complete(@RequestBody AllDemoDto allDemoDto) {
        Boolean approved=allDemoDto.getSubmitApproved();
        String comment= allDemoDto.getSubmitComment();
        String taskId= allDemoDto.getSubmitTaskId();

        Map<String, Object> taskVariables = new HashMap<>();
        taskVariables.put("approved", approved?"Y":"N");

        //审核结果和审核意见都封装为JSON然后放在评论里，后续需要进行逆操作。
        ObjectMapper objectMapper = new ObjectMapper();
        Map<String, String> map=new HashMap<String,String>();
        map.put("approved", approved?"Y":"N");
        map.put("comment", comment);

        try {
            String json = objectMapper.writeValueAsString(map);
            taskService.addComment(taskId, null, json);
            taskService.complete(taskId, taskVariables);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }


        return CommonResult.success("审批成功");
    }



}
